import React from 'react';
import PropTypes from 'prop-types';
import { Tag, Balloon, Button } from '@teamix/ui';
import Pagination from 'components/commonPagination';
import './index.scss';
import exceed from 'utils/apimap';
import track from 'utils/track';
import ListEmpty from 'atComponents/ListEmpty';
// import utils from 'utils';
import isEqual from 'lodash.isequal';
import IssueIdialog from 'components/dependencyIssueDetailDialog';
import UsersAvatar from '@alife/teamix-at-users-avatar';
import { YunxiaoIcon, Title, YunxiaoTable } from '@alife/devops-ui';
import dayjs from 'dayjs';
import PathEllipsis from 'components/pathEllipsis';
import utils from 'utils';
import AutoFixConfirm from './autoFIxConfirm';
import MrIcon from './mrIcon';
import intl from '../../locale';

const { Tooltip } = Balloon;

const levelMap = {
  Blocker: 'red',
  Major: 'blue',
  Critical: 'orange',
};
export default class IssuesTable extends React.Component {
  static propTypes = {
    headerTitle: PropTypes.string,
    // 表格状态分类
    issue_status: PropTypes.string,
  };

  static defaultProps = {
    headerTitle: '',
    issue_status: '',
  };

  constructor(props) {
    super(props);
    this.state = {
      expandRow: true,
      dataSource: null,
      page: 1,
      openRowKeys: this.props.issue_status === 'unresolved' ? [0] : [],
      isLoading: true,
      isModalOpen: false,
      issue: null,
      pageSize: 10,
    };
  }

  componentDidMount() {
    const { buildResult, filterParams } = this.props;
    this.listBuildIssues(buildResult, filterParams);
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    const { buildResult: nextBuildResult, filterParams: nextFilterParams } = nextProps;
    const { buildResult, filterParams } = this.props;
    if (
      nextBuildResult &&
      buildResult &&
      (nextBuildResult.id !== buildResult.id || !isEqual(filterParams, nextFilterParams))
    ) {
      this.listBuildIssues(nextBuildResult, nextFilterParams);
    }
  }

  listBuildIssues = (buildResult, filterParams, page = 1, per_page) => {
    const { pathResource } = window.FORCE;
    if (buildResult) {
      this.setState({
        isLoading: true,
      });

      const datas = {};
      if (filterParams.issue_level_list && filterParams.issue_level_list.length > 0) {
        datas.level = filterParams.issue_level_list.join(',');
      }
      if (filterParams.build_language) {
        datas.build_language = filterParams.build_language;
      }
      if (filterParams.issue_filter) {
        datas.issue_filter = filterParams.issue_filter;
      }

      datas.issue_type = filterParams.issue_type;
      const isUnresolvedStatus = this.props.issue_status === 'unresolved';
      const { pageSize } = this.state;
      exceed
        .forceFetch({
          api: 'projects.builds.list.issues',
          params: {
            projectId: pathResource.id,
            buildResultId: buildResult.id,
          },

          data: {
            page,
            per_page: per_page || pageSize,
            issue_status: isUnresolvedStatus ? 'unresolved,new' : this.props.issue_status,
            ...datas,
          },
        })
        .then((data) => {
          // url携带参数则将弹窗弹出指定Issue
          let newIssue = null;
          if (isUnresolvedStatus) {
            const auto_open_issue_id = utils.getUrlSearchParam('auto_open_issue_id') || '';
            newIssue = data.list.find((item) => {
              return item.build_issue_id === Number(auto_open_issue_id);
            });
          }
          this.setState({
            dataSource: data,
            page,
            isLoading: false,
            // eslint-disable-next-line react/no-access-state-in-setstate
            issue: newIssue || this.state.issue,
            isModalOpen: !!newIssue,
          });
        })
        .catch((err) => {
          console.error(err);
          this.setState({
            isLoading: false,
          });
        });
    }
  };

  toggleRow = () => {
    const { expandRow } = this.state;
    this.setState({
      expandRow: !expandRow,
    });
  };

  onPageNoChange = (page) => {
    const { buildResult, filterParams } = this.props;
    this.listBuildIssues(buildResult, filterParams, page);
  };

  onPageSizeChange = (pageSize) => {
    const { buildResult, filterParams } = this.props;
    this.listBuildIssues(buildResult, filterParams, 1, pageSize);
    this.setState({
      pageSize,
    });
  };

  onRowOpen = (openRowKeys) => {
    this.setState({
      openRowKeys,
    });
  };

  renderLevel = (value, index, record) => {
    const { blocker_count, critical_count, major_count } = record;
    return (
      <div style={{ marginLeft: '-4px' }}>
        {blocker_count ? (
          <span style={{ marginRight: 8 }}>
            <Tag color={levelMap.Blocker || undefined}>Blocker {blocker_count}</Tag>
          </span>
        ) : null}
        {critical_count ? (
          <span style={{ marginRight: 8 }}>
            <Tag color={levelMap.Critical || undefined}>Critical {critical_count}</Tag>
          </span>
        ) : null}
        {major_count ? (
          <span>
            <Tag color={levelMap.Major || undefined}>Major {major_count}</Tag>
          </span>
        ) : null}
      </div>
    );
  };

  renderOwner = (value, index, record) => {
    return (
      <div style={{ marginLeft: 5, display: 'flex', alignItems: 'center' }}>
        <UsersAvatar
          dataSource={[
            {
              id: '',
              name: value,
              avatarUrl: record.avatar || '',
            },
          ]}
          size="xs"
          borderColor={'#f7f7f7'}
        />

        <Title trigger={<span style={{ marginLeft: 8 }}>{value}</span>} align="t">
          <span>{value}</span>
        </Title>
      </div>
    );
  };

  handleRowClick = (record) => {
    this.setState({
      isModalOpen: true,
      issue: record,
    });
  };

  onClose = () => {
    this.setState({
      issue: null,
      isModalOpen: false,
    });

    // 弹窗关闭时将url param清空
    const auto_open_issue_id = utils.getUrlSearchParam('auto_open_issue_id') || '';
    if (auto_open_issue_id) {
      window.history.replaceState({}, null, '/');
    }
  };

  onTrigger = (bid) => {
    if (bid) {
      track({
        action: 'security-remediation',
        page: 'repo-security-dependency',
        type: '',
        control: '',
      });
    } else {
      track({
        action: 'security-recommendation',
        page: 'repo-security-dependency',
        type: '',
        control: '',
      });
    }
  };

  renderTitle = (value, index, record) => {
    // 第一个出现自动修复且第一次访问时，自动出现提示引导
    const { build_patch_id } = record;
    let isNeedConfrim = false;
    if (build_patch_id) {
      const { dataSource } = this.state;
      const list = (dataSource && dataSource.list) || [];
      const patchList = list.filter((item) => {
        return item.build_patch_id;
      });
      const curPatchIndex = patchList.findIndex((item) => {
        return item.build_issue_id === record.build_issue_id;
      });
      isNeedConfrim = curPatchIndex === 0;
    }
    const titleIcon = (
      <Tooltip
        trigger={
          <YunxiaoIcon
            onMouseEnter={() => this.onTrigger(build_patch_id)}
            type="resource-pool-line"
            className={`suggestion-icon ${build_patch_id ? 'auto-fix' : ''}`}
          />
        }
        align="t"
      >
        {build_patch_id
          ? intl.get({
              id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.TheRecommendedSolutionSupportsAutomatic',
              defaultMessage: '已推荐修复方案,支持自动修复',
            })
          : intl.get({
              id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.RecommendedSolution',
              defaultMessage: '已推荐修复方案',
            })}
      </Tooltip>
    );

    const titleConfirm = <AutoFixConfirm trigger={titleIcon} isNeedConfrim={isNeedConfrim} />;

    const content = (
      <Tooltip trigger={<div className="table-cell-one-line has-icon">{value}</div>} align="t">
        {value}
      </Tooltip>
    );

    // 直接依赖ICON
    const directlyIcon = !record.is_indirectly && (
      <Tooltip
        trigger={<YunxiaoIcon type="quote-line-2" className="directly-icon inline" />}
        align="t"
      >
        {intl.get({
          id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.DirectDependency',
          defaultMessage: '直接依赖',
        })}
      </Tooltip>
    );

    const mrIconJsx = (
      <MrIcon
        codeReview={{
          id: record.merge_request_id,
          state: record.merge_request_state,
        }}
      />
    );

    return (
      <>
        <span style={{ width: '38px' }}>&nbsp;</span>
        <div className="dependency-tr-title">
          {directlyIcon}
          {content}
          {this.props.issue_status.toLowerCase() === 'unresolved' && record.suggestion
            ? titleConfirm
            : null}
          {mrIconJsx}
        </div>
      </>
    );
  };

  renderValue = (value) => {
    const trigger = <div className="table-cell-one-line">{value}</div>;

    return (
      <Tooltip trigger={trigger} align="t">
        {value}
      </Tooltip>
    );
  };

  renderFile = (value) => {
    return (
      <div className="dependency-file-name-content">
        <PathEllipsis path={value} isLastItemMoreImportant={false} />
      </div>
    );
  };

  isHasFilter() {
    const { filterParams } = this.props;
    if (!filterParams) {
      return false;
    }
    if (
      filterParams.build_language ||
      (filterParams.issue_level_list && filterParams.issue_level_list.length > 0) ||
      filterParams.issue_filter
    ) {
      return true;
    } else {
      return false;
    }
  }

  renderEmptyList() {
    const { issue_status, buildResult, restartScan, isStarting } = this.props;
    if (this.isHasFilter()) {
      return (
        <ListEmpty
          content={''}
          desc={intl.get({
            id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.NoSearchResults',
            defaultMessage: '搜索无结果',
          })}
          size="small"
          className="table-result"
          imgType="search"
        />
      );
    } else {
      // FAIL和WARNNING状态，没有返回issues，判断检测时间，超过30天，显示PRD里文案「xxx仅保持30天据」
      const { state, gmt_create } = buildResult;
      if (
        issue_status === 'unresolved' &&
        dayjs(gmt_create).add(30, 'day') < dayjs() &&
        state &&
        ['FAIL', 'WARNNING'].includes(state.toUpperCase())
      ) {
        return (
          <div className="retry-scan-list-empty">
            <ListEmpty
              content={''}
              desc={intl.get({
                id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.DetectionMoreThanDaysNot',
                defaultMessage: '检测已超30天，不支持查看问题详情',
              })}
              className="table-result"
              size="small"
              image="none"
              btns={[
                <Button
                  type="primary"
                  style={{ width: 88, marginTop: 8 }}
                  loading={isStarting}
                  size="small"
                  onClick={() => {
                    restartScan(false);
                  }}
                >
                  {intl.get({
                    id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.ReCheck',
                    defaultMessage: '重新检测',
                  })}
                </Button>,
              ]}
            />
          </div>
        );
      }
      return (
        <ListEmpty
          content={''}
          desc={
            issue_status === 'unresolved'
              ? intl.get({
                  id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.TheCurrentBranchHasNo',
                  defaultMessage: '当前分支暂无未解决的问题',
                })
              : intl.get({
                  id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.TheCurrentBranchHasNo.1',
                  defaultMessage: '当前分支暂无已解决的问题',
                })
          }
          className="table-result"
          size="small"
          imgType="500"
        />
      );
    }
  }

  expandedRowRender = () => {
    // record, index
    const { page, dataSource, isLoading } = this.state;
    const list = (dataSource && dataSource.list) || [];
    const amount = (dataSource && dataSource.amount) || 0;
    return (
      <React.Fragment>
        {isLoading || list.length > 0 ? (
          <div className="build-issue-list-subtable">
            <YunxiaoTable
              className={'issue-table dependency-issue-table'}
              dataSource={list}
              hasBorder={false}
              hasHeader={false}
              loading={isLoading}
              onRowClick={this.handleRowClick}
            >
              {/* <YunxiaoTable.Column title="pad" dataIndex="id" cell={renderPaddingCell} /> */}
              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.RelyOn',
                  defaultMessage: '依赖',
                })}
                dataIndex="title"
                className="dependency-issue-title-col"
                width={100}
                cell={this.renderTitle}
              />
              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.Version',
                  defaultMessage: '版本',
                })}
                dataIndex="content"
                className="dependency-issue-version-col"
                width={60}
                cell={this.renderValue}
              />
              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.File',
                  defaultMessage: '文件',
                })}
                dataIndex="file_name"
                className="dependency-issue-file-col"
                width={100}
                cell={this.renderFile}
              />
              <YunxiaoTable.Column
                title={intl.get({
                  id: 'code-assets.components.dependencyBuildIssuesList.issuesTable.Vulnerability',
                  defaultMessage: '漏洞',
                })}
                dataIndex="level"
                className="dependency-issue-level-col"
                width={100}
                cell={this.renderLevel}
              />
              {/* <Table.Column title="问题引入人" dataIndex="owner" className="issue-owner-col" cell={this.renderOwner} /> */}
              {/* <Table.Column title="引入时间" dataIndex="intro_time" className="issue-time-col" cell={(value) => { return utils.getBeautyTime(value); }} /> */}
            </YunxiaoTable>
            <Pagination
              onChange={this.onPageNoChange}
              onPageSizeChange={this.onPageSizeChange}
              pageSize={this.state.pageSize}
              current={page}
              total={amount}
              showJump={false}
              pageSizeSelector={false}
              footerProps={{
                style: { margin: 0, paddingRight: 40 },
              }}
            />
          </div>
        ) : (
          this.renderEmptyList()
        )}
      </React.Fragment>
    );
  };

  render() {
    const { headerTitle, buildResult, updateCommitId } = this.props;
    const headerDataSource = [{ title: headerTitle, id: 0 }];
    const { openRowKeys, dataSource, isModalOpen, issue } = this.state;
    const { pathResource } = window.FORCE;
    return (
      <div>
        <YunxiaoTable
          dataSource={headerDataSource}
          hasBorder={false}
          expandedRowRender={this.expandedRowRender}
          expandedRowIndent={[0, 0]}
          hasHeader={false}
          openRowKeys={openRowKeys}
          onRowClick={this.toggleRow}
          onRowOpen={this.onRowOpen}
        >
          <YunxiaoTable.Column
            title="Title"
            dataIndex="title"
            cell={(item) => {
              return (
                <span className="sub-title" style={{ marginLeft: '-19px' }}>
                  {item}
                  {dataSource ? ` · ${dataSource.amount}` : null}
                </span>
              );
            }}
          />
        </YunxiaoTable>
        {isModalOpen && (
          <IssueIdialog
            issue={issue}
            onClose={this.onClose}
            build={buildResult}
            updateCommitId={updateCommitId}
            projectId={pathResource.id}
          />
        )}
      </div>
    );
  }
}
